import express from 'express'
import { Response, Request } from "express"

const router = express.Router()

import { success, failure } from '../utils/responses'
import { AppDataSource } from "../config/database"
import { BadRequest, NotFound } from "http-errors"
import { Post } from "../entities/Post";
import { FindManyOptions } from "typeorm";
import { AuthRequest } from "../middlewares/user-auth";
import { Photo } from "../entities/Photo";

enum OrderType {
  Hot = 1, // 最热
  New = 2 // 最新
}

/**
 * 查询帖子列表
 */
router.get('/', async function (req: Request, res: Response) {
  try {
    const query = req.query

    const orderType = Number(query.orderType) || 1 // 排序方式
    const currentPage = Math.abs(Number(query.currentPage)) || 1 // 当前页
    const pageSize = Math.abs(Number(query.pageSize)) || 10 // 每页条数
    const offset = (currentPage - 1) * pageSize // 偏移量

    const postRepository = AppDataSource.getRepository(Post)

    // 排序选项
    let orderOptions: object
    if (orderType === OrderType.Hot) {
      orderOptions = {
        likeCount: 'DESC', // 先按点赞数排序
        updatedAt: "DESC"
      }
    } else if (orderType === OrderType.New) {
      orderOptions = {
        updatedAt: "DESC", // 先按发布时间排序
        likeCount: 'DESC'
      }
    }

    const findOptions: FindManyOptions = {
      relations: {
        author: true,
        photo: true,
        comment: true
      },
      order: orderOptions,
      skip: offset,
      take: pageSize
    }

    const [posts, totalCount] = await postRepository.findAndCount(findOptions)

    // 去除不需要的字段
    const filterPosts = posts.map(post => {
      const { id, title, content, photo, likeCount, comment, shareCount, updatedAt, author } = post;
      return {
        id,
        title,
        content,
        likeCount,
        commentCount: comment.length,
        shareCount,
        photo,
        updatedAt,
        author: {
          id: author.id,
          username: author.username,
          avatar: author.avatar
        }
      }
    })

    success(res, '查询帖子列表成功', {
      posts: filterPosts,
      pagination: {
        totalPage: Math.ceil(totalCount / pageSize),
        currentPage,
        pageSize,
        totalCount
      }
    })
  } catch (error) {
    failure(res, error)
  }
})

/**
 * 查询帖子详情
 */
router.get('/:id', async function (req: Request, res: Response) {
  try {
    const postId = Number(req.params.id)
    if (isNaN(postId)) throw new BadRequest("请传入合法的帖子id")

    const postRepository = AppDataSource.getRepository(Post)
    const post = await postRepository.findOne({
      relations: {
        author: true,
        photo: true,
        comment: true
      },
      where: {
        id: postId
      }
    })

    if (!post) {
      throw new NotFound(`ID为${postId}的帖子未找到`)
    }

    const { id, username, avatar } = post.author // 取出作者的id、用户名和头像
    const commentCount = post.comment.length // 获取评论数
    delete post.author // 删除post的author字段
    delete post.comment // 删除post的comment字段
    success(res, '查询帖子详情成功', {
      ...post,
      author: {
        id,
        username,
        avatar
      },
      commentCount
    })
  } catch (error) {
    failure(res, error)
  }
})

/**
 * 创建帖子
 */
router.post('/', async function (req: Request, res: Response) {
  try {
    const postBody = req.body
    const title = postBody.title as string
    const content = postBody.content as string
    const imageList = (postBody.imageList || []) as string[]

    // 参数校验
    if (!title || !content) {
      throw new BadRequest('标题或内容不能为空')
    }

    const photoRepository = AppDataSource.getRepository(Photo)

    const photoList: Photo[] = [] // 创建一个空数组，用于存储要提交图片

    for (let i in imageList) {
      const photo = new Photo()
      photo.photoUrl = imageList[i]
      await photoRepository.save(photo)
      photoList.push(photo)
    }

    // 创建新帖
    const postRepository = AppDataSource.getRepository(Post)
    const newPost = postRepository.create({
      title,
      content,
      authorId: (req as AuthRequest).id,
      photo: photoList
    })

    // 保存帖子到数据库
    await postRepository.save(newPost)

    success(res, '帖子创建成功', newPost)
  } catch (error) {
    failure(res, error)
  }
})


export default router
